package cn.ronghuanet.auth.service.impl;

import cn.ronghuanet.auth.domain.Role;
import cn.ronghuanet.auth.dto.RolePermissionDTO;
import cn.ronghuanet.auth.mapper.RoleMapper;
import cn.ronghuanet.auth.query.RoleQuery;
import cn.ronghuanet.auth.service.IRoleService;
import cn.ronghuanet.basic.service.impl.BaseServiceImpl;
import cn.ronghuanet.basic.utils.PageList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;

/**
 * 类上面使用哪一个事务,类里面所有的方法都是这个事务规则,如果方法需要其他的事务规则,就给方法单独是设置
 * 继承BaseServiceImpl  到时候就可以不用写公共方法,但是如果某一个公共方法需要由自己的逻辑,重写该方法自己写业务逻辑即可
 * 实现自己的业务接口类,为了写自己的业务方法
 */
@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class RoleServiceImpl extends BaseServiceImpl<Role> implements IRoleService {

    @Autowired
    private RoleMapper roleMapper;


    @Transactional
    @Override
    public void add(Role role) {
        // 通过sn和name查询一次
        Role roleByDb = roleMapper.loadByName(role.getName());
        // 如果查询出来不为null,说明sn和name之前在数据库已经存在,返回一个错误信息:"标识和名字已经存在,请修改"
        if(Objects.nonNull(roleByDb)){
            throw new RuntimeException("角色名称已经存在,请修改");
        }
        roleByDb = roleMapper.loadBySn(role.getSn());
        // 如果查询出来不为null,说明sn和name之前在数据库已经存在,返回一个错误信息:"标识和名字已经存在,请修改"
        if(Objects.nonNull(roleByDb)){
            throw new RuntimeException("角色标识已经存在,请修改");
        }
        // 判断查询结果是否为null,如果为null说明sn和name之前在数据库不存在,就可以保存成功,
        roleMapper.insert(role);
    }

    @Transactional
    @Override
    public void update(Role role) {
        // 通过sn和name查询一次
        // 判断查询结果是否为null,如果为null说明sn和name之前在数据库不存在,就可以保存成功,
        Role roleByDb = roleMapper.loadByName(role.getName());
        // 如果查询出来不为null,说明sn和name之前在数据库已经存在,判断查询来的对象的id是否等于当前要修改角色的id
        // 如果id不相等,,返回一个错误信息:"标识和名字已经存在,请修改"
        // 如果id相等,就可以正常修改
        if(Objects.nonNull(roleByDb) && !roleByDb.getId().equals(role.getId())){
            throw new RuntimeException("角色名称已经存在,请修改");
        }
        roleByDb = roleMapper.loadBySn(role.getSn());
        if(Objects.nonNull(roleByDb) && !roleByDb.getId().equals(role.getId())){
            throw new RuntimeException("角色标识已经存在,请修改");
        }
        roleMapper.update(role);
    }

    @Transactional
    @Override
    public void setRolePermission(RolePermissionDTO dto) {
        // 1 根据roleId先删除这个角色原来绑定的权限
        roleMapper.deleteByRoleId(dto.getRoleId());

        // 2 新增角色和权限的关联关系
        // 注意:1个角色是可以有多个权限的,怎么写?
        // 方式一: 循环dto.permissionSns 每次循环,都调用一次insert(), 不建议使用,减少操作数据库
        // 方案二: 批量新增Available
        roleMapper.saveRolePermission(dto.getRoleId(),dto.getPermissionSns());
    }

    @Override
    public List<String> getRolePermissionSns(Long roleId) {
        return roleMapper.getRolePermissionSns(roleId);
    }
}
